<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\command;

use app\enum\CommonEnum;
use app\enum\KsCodeEnum;
use app\enum\RedisEnum;
use app\model\BatchCreateContentModel;
use app\model\BatchCreateModel;
use app\model\BatchCreateSchemaUriModel;
use app\model\ClientAccountModel;
use app\model\KsAdvertiserSchemaCodeModel;
use app\model\KsBuildProjectModel;
use app\service\client\AccountService;
use app\service\kuaishou\AdvertiserService;
use think\console\Input;
use think\console\Output;
use think\facade\Cache;
use think\facade\Log;

class KsBatchProjectCreateWork extends BaseWork
{
    public const REDIS_KEY = 'habo_new_media:task:ks_batch_project:' . RedisEnum::REDIS_LIST;

    protected function configure()
    {
        // 指令配置
        $this->setName('ks_batch_project_create_work');
        $this->setDescription('磁力引擎-批量搭建项目');
    }

    protected function execute(Input $input, Output $output)
    {
        try {
            set_time_limit(0);
            ini_set('memory_limit', '-1');

            $output->writeln('=======磁力引擎-批量搭建智能托管项目start ' . date('Y-m-d H:i:s', time()) . '=======');
            $redis = Cache::store('redis')->handler();

            $schemaUriArr = [];
            // 超过5min就停止
            $t = time();
            $runTime = 5 * 60;
            while (time() - $t <= $runTime) {
                $id = intval($redis->lpop(self::REDIS_KEY));
                if (! $id) {
                    break;
                }

                $list = $this->_getContentList($id);
                if (! $list) {
                    $output->writeln('数据不存在！');
                    continue;
                }

                $count = count($list);
                foreach ($list as $v) {
                    $arr = json_decode($v['content_json'], true);
                    if ($arr['schedule']) {
                        $arr['schedule'] = $this->_formatSchedule($arr['schedule']);
                    }

                    if (! empty($arr['begin_time'])) {
                        $arr['begin_time'] = (time() + 60) * 1000;
                    }

                    // token:barrel:2:1
                    $accessToken = AccountService::getToken(CommonEnum::KS_MEDIA, $arr['advertiser_id']);
                    // $accessToken = '8b167cf95c3b6406dcdb74a7f342613c';
                    if (! $accessToken) {
                        $output->writeln('token不存在！advertiser_id:' . $arr['advertiser_id']);
                        continue;
                    }

                    $result = $this->_createProject($accessToken, $arr);

                    $schemaUriArr[] = [
                        'schema_uri' => $arr['schema_uri'],
                        'advertiser_id' => $arr['advertiser_id'],
                    ];

                    if (! $result) {
                        $errorMsg = date('Y-m-d H:i:s ', time()) . ' 批量操作智能托管项目失败,batch_content_id:' . $v['id'] . ' 接口msg:' . AdvertiserService::getError(0);
                        $output->writeln($errorMsg);
                        $this->_updateContentData($v['id'], ['error_msg' => $errorMsg]);
                        continue;
                    }

                    if ($result['code'] != KsCodeEnum::SUCCESS) {
                        $errorMsg = date('Y-m-d H:i:s', time()) . ' 批量操作智能托管项目失败,batch_content_id:' . $v['id'] . ' msg:' . $result['message'] . ',request_id:' . $result['request_id'];
                        $output->writeln($errorMsg);
                        $this->_updateContentData($v['id'], ['error_msg' => $errorMsg]);
                        continue;
                    }
                    $result = $this->_updateContentData($v['id'], ['api_return_id' => $result['data']['project_id']]);
                }

                $successNum = $this->_contentCount($id);
                if ($successNum != $count) {
                    // 记录错误
                    Log::channel('ks_baidu_batch')->error(json_encode([
                        'id' => $id,
                        'num' => $count,
                        'finish_num' => $successNum,
                        'list' => $list,
                        'sql' => (new BatchCreateContentModel())->getLastSql(),
                    ], JSON_UNESCAPED_UNICODE));

                    $redis->rpush(self::REDIS_KEY, $id);
                    $redis->expire(self::REDIS_KEY, 7 * 24 * 3600);
                    $result = $this->_updateBatchCreateData($id, [
                        'status' => BatchCreateModel::STATUS_MULTI_ENABLE,
                        'num' => $count,
                        'success_num' => $successNum,
                    ]);
                } else {
                    $result = $this->_updateBatchCreateData($id, [
                        'status' => BatchCreateModel::STATUS_ENABLE,
                        'num' => $count,
                        'success_num' => $successNum,
                    ]);
                }

                if ($result <= 0) {
                    $output->writeln(date('Y-m-d H:i:s', time()) . ' 修改智能托管项目状态失败,batch_id:' . $id);
                }

                /*$schemaUriArr[] = [
                    'advertiser_id' => '15044511',
                    'schema_uri' => 'baiduboxlite://v1/easybrowse/open?url=https%3A%2F%2Factivity.baidu.com%2Fincentive%2FincentiveHome%3Fproductid%3D2%26idfrom%3Dfeitian%26channel%3Dwangzhuan&newbrowser=1&forbidautorotate=1&type=immerse&backlocation=1&bannerswitch=1&append=1&zoomswitch=0&needschema=1&stay=1&logargs=%7B%22channel%22%3A%221028416t%22%2C%22ext%22%3A%22%7B%5C%22id%5C%22%3A%5C%22%5C%22%2C%5C%22rid%5C%22%3A%5C%2261ZZT1cfcadfc56bb4%5C%22%2C%5C%22adid%5C%22%3A%5C%2261ZZT%5C%22%2C%5C%22category%5C%22%3A%5C%22%5C%22%2C%5C%22sid%5C%22%3A%5C%22%7Bqueryid%7D%5C%22%2C%5C%22platform%5C%22%3A%5C%22feitian%5C%22%2C%5C%22dppage%5C%22%3A%5C%22wangzhuan%5C%22%7D%22%2C%22from%22%3A%22openbox%22%2C%22page%22%3A%22other%22%2C%22source%22%3A%221028416t%22%2C%22type%22%3A%22%22%2C%22value%22%3A%22url%22%7D&needlog=1&stay=1&imei5=__IMEI2__&reqid=__REQUESTID__&traceid=__TRACEREQID__&ad_id=__CID__',
                ];*/
                if ($schemaUriArr) {
                    $result = $this->_setSchemaCode($schemaUriArr);
                }

                $output->writeln('=======磁力引擎-批量搭建智能托管项目end ' . date('Y-m-d H:i:s', time()) . '=======');
            }
        } catch (\Exception $e) {
            $output->writeln($e->getMessage());
        }
    }

    private function _getProjectInfo(int $batchId = 0): array
    {
        $info = (new KsBuildProjectModel())->where('batch_id', $batchId)->field(true)->find();
        if (! $info) {
            return [];
        }

        return $info->toArray();
    }

    /**
     * 更新直达链接CODE.
     * @param array $schemaUriArr 链接数组
     */
    private function _setSchemaCode(array $schemaUriArr = []): bool
    {
        $advertiserId = $schemaUriArr[0]['advertiser_id'];
        $advertiserInfo = $this->_getAdvertiserInfo($advertiserId);
        if (! $advertiserInfo) {
            return false;
        }

        $uriList = $this->_getSchemaUriList($advertiserId);
        if (! $uriList) {
            return false;
        }

        $allData = [];
        foreach ($schemaUriArr as $v) {
            if (! isset($uriList[$v['schema_uri']])) {
                continue;
            }
            $uriInfo = $uriList[$v['schema_uri']];

            if ($uriInfo['has_use'] == BatchCreateSchemaUriModel::USE) {
                continue;
            }

            $allData[] = [
                'company_id' => $advertiserInfo['company_id'],
                'client_id' => $advertiserInfo['client_id'],
                'advertiser_id' => $v['advertiser_id'],
                'app_id' => $uriInfo['app_id'],
                'material_id' => $uriInfo['material_id'],
                'create_time' => time(),
            ];
        }
        if ($this->_insertAllCodeData($allData)) {
            $this->_updateSchemaCodeTime($advertiserId);
            return true;
        }
        return false;
    }

    /**
     * 获取账户信息.
     */
    private function _getAdvertiserInfo(string $advertiserId = ''): array
    {
        $info = (new ClientAccountModel())->where('advertiser_id', $advertiserId)->field(true)->find();

        if (! $info) {
            return [];
        }

        return $info->toArray();
    }

    /**
     * 获取直达信息.
     */
    private function _getSchemaUriList(string $advertiserId = ''): array
    {
        return (new BatchCreateSchemaUriModel())->where('advertiser_id', $advertiserId)->column('*', 'schema_uri');
    }

    /**
     * 批量插入数据.
     * @param array $data 数据
     */
    private function _insertAllCodeData(array $data = []): bool
    {
        if (empty($data)) {
            return true;
        }
        $result = (new KsAdvertiserSchemaCodeModel())->insertAll($data);

        if ($result <= 0) {
            return false;
        }

        return true;
    }

    /**
     * 修改物料update_time.
     * @param string $advertiserId 账户id
     * @param array $appId appid
     */
    private function _updateSchemaCodeTime(string $advertiserId = '', array $appId = [])
    {
        return (new KsAdvertiserSchemaCodeModel())->where('advertiser_id', $advertiserId)
//            ->whereIn('app_id', $appId)
            ->update(['update_time' => 0]);
    }

    /**
     * 格式化投放排期
     */
    private function _formatSchedule(array $arr = []): string
    {
        $result = [];
        foreach ($arr as $v) {
            if ($v) {
                $result[] = '[' . implode(',', $v) . ']';
            } else {
                $result[] = '[]';
            }
        }
        return '[' . implode(',', $result) . ']';
    }

    /**
     * 修改信息.
     */
    private function _updateBatchCreateData(int $id = 0, array $data = []): bool
    {
        $data['update_time'] = time();
        $result = (new BatchCreateModel())->where('id', $id)->data($data)->save();

        if ($result <= 0) {
            return false;
        }

        return true;
    }

    /**
     * 获取总数.
     */
    private function _contentCount(int $batchId = 0): int
    {
        return (new BatchCreateContentModel())->where('batch_id', $batchId)->whereNotNull('api_return_id')->field(true)->count();
    }

    /**
     * 修改信息.
     */
    private function _updateContentData(int $id = 0, array $data = []): bool
    {
        $data['update_time'] = time();
        $result = (new BatchCreateContentModel())->where('id', $id)->data($data)->save();

        if ($result <= 0) {
            return false;
        }

        return true;
    }

    /**
     * 获取列表.
     */
    private function _getContentList(int $batchId = 0): array
    {
        return (new BatchCreateContentModel())->where('batch_id', $batchId)->whereNull('api_return_id')->whereNull('error_msg')->field(true)->select()->toArray();
    }

    /**
     * 创建项目.
     */
    private function _createProject(string $accessToken = '', array $params = [])
    {
        $headers = [
            'Access-Token' => $accessToken,
            'Content-Type' => 'application/json',
        ];

        return AdvertiserService::createProject($headers, $params);
    }
}
